home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / dskut / aspisrc.zip / MSD_DIR.C < prev    next >
C/C++ Source or Header  |  1992-01-26  |  4KB  |  219 lines

  1. /*
  2.  * @(#)msd_dir.c 1.4 87/11/06    Public Domain.
  3.  *
  4.  *  A public domain implementation of BSD directory routines for
  5.  *  MS-DOS.  Written by Michael Rendell ({uunet,utai}michael@garfield),
  6.  *  August 1897
  7.  */
  8.  
  9. #include    <sys/types.h>
  10. #include    <sys/stat.h>
  11. #include    "msd_dir.h"
  12. #ifndef __TURBOC__
  13. #include    <malloc.h>
  14. #endif
  15. #include    <string.h>
  16. #include    <dos.h>
  17.  
  18. #ifndef    NULL
  19. # define    NULL    0
  20. #endif    /* NULL */
  21.  
  22. #ifndef    MAXPATHLEN
  23. # define    MAXPATHLEN    255
  24. #endif    /* MAXPATHLEN */
  25.  
  26. /* attribute stuff */
  27. #define    A_RONLY        0x01
  28. #define    A_HIDDEN    0x02
  29. #define    A_SYSTEM    0x04
  30. #define    A_LABEL        0x08
  31. #define    A_DIR        0x10
  32. #define    A_ARCHIVE    0x20
  33.  
  34. /* dos call values */
  35. #define    DOSI_FINDF    0x4e
  36. #define    DOSI_FINDN    0x4f
  37. #define    DOSI_SDTA    0x1a
  38.  
  39. #define    Newisnull(a, t)        ((a = (t *) malloc(sizeof(t))) == (t *) NULL)
  40. /* #define    ATTRIBUTES        (A_DIR | A_HIDDEN | A_SYSTEM) */
  41. #define ATTRIBUTES    (A_RONLY | A_SYSTEM | A_DIR)
  42.  
  43. /* what find first/next calls look use */
  44. typedef struct {
  45.     char        d_buf[21];
  46.     char        d_attribute;
  47.     unsigned short    d_time;
  48.     unsigned short    d_date;
  49.     long        d_size;
  50.     char        d_name[13];
  51. } Dta_buf;
  52.  
  53. static    char    *getdirent();
  54. static    void    mysetdta();
  55. static    void    free_dircontents();
  56.  
  57. static    Dta_buf        dtabuf;
  58. static    Dta_buf        *dtapnt = &dtabuf;
  59. static    union REGS    reg, nreg;
  60.  
  61. #if    defined(M_I86LM)
  62. static    struct SREGS    sreg;
  63. #endif
  64.  
  65. DIR    *
  66. opendir(name)
  67.     char    *name;
  68. {
  69.     struct    stat        statb;
  70.     DIR            *dirp;
  71.     char            c;
  72.     char            *s;
  73.     struct _dircontents    *dp;
  74.     char            nbuf[MAXPATHLEN + 1];
  75.     
  76.     if (stat(name, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR)
  77.         return (DIR *) NULL;
  78.     if (Newisnull(dirp, DIR))
  79.         return (DIR *) NULL;
  80.     if (*name && (c = name[strlen(name) - 1]) != '\\' && c != '/')
  81.         (void) strcat(strcpy(nbuf, name), "\\*.*");
  82.     else
  83.         (void) strcat(strcpy(nbuf, name), "*.*");
  84.     dirp->dd_loc = 0;
  85.     mysetdta();
  86.     dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) NULL;
  87.     if ((s = getdirent(nbuf)) == (char *) NULL)
  88.         return dirp;
  89.     do {
  90.         if (Newisnull(dp, struct _dircontents) || (dp->_d_entry =
  91.             malloc((unsigned) (strlen(s) + 1))) == (char *) NULL)
  92.         {
  93.             if (dp)
  94.                 free((char *) dp);
  95.             free_dircontents(dirp->dd_contents);
  96.             return (DIR *) NULL;
  97.         }
  98.         if (dirp->dd_contents)
  99.             dirp->dd_cp = dirp->dd_cp->_d_next = dp;
  100.         else
  101.             dirp->dd_contents = dirp->dd_cp = dp;
  102.         (void) strcpy(dp->_d_entry, s);
  103.         dp->_d_next = (struct _dircontents *) NULL;
  104.     } while ((s = getdirent((char *) NULL)) != (char *) NULL);
  105.     dirp->dd_cp = dirp->dd_contents;
  106.  
  107.     return dirp;
  108. }
  109.  
  110. void
  111. closedir(dirp)
  112.     DIR    *dirp;
  113. {
  114.     free_dircontents(dirp->dd_contents);
  115.     free((char *) dirp);
  116. }
  117.  
  118. struct direct    *
  119. readdir(dirp)
  120.     DIR    *dirp;
  121. {
  122.     static    struct direct    dp;
  123.     
  124.     if (dirp->dd_cp == (struct _dircontents *) NULL)
  125.         return (struct direct *) NULL;
  126.     dp.d_namlen = dp.d_reclen =
  127.         strlen(strcpy(dp.d_name, dirp->dd_cp->_d_entry));
  128.     strlwr(dp.d_name);        /* JF */
  129.     dp.d_ino = 0;
  130.     dirp->dd_cp = dirp->dd_cp->_d_next;
  131.     dirp->dd_loc++;
  132.  
  133.     return &dp;
  134. }
  135.  
  136. void
  137. seekdir(dirp, off)
  138.     DIR    *dirp;
  139.     long    off;
  140. {
  141.     long            i = off;
  142.     struct _dircontents    *dp;
  143.  
  144.     if (off < 0)
  145.         return;
  146.     for (dp = dirp->dd_contents ; --i >= 0 && dp ; dp = dp->_d_next)
  147.         ;
  148.     dirp->dd_loc = off - (i + 1);
  149.     dirp->dd_cp = dp;
  150. }
  151.  
  152. long
  153. telldir(dirp)
  154.     DIR    *dirp;
  155. {
  156.     return dirp->dd_loc;
  157. }
  158.  
  159. static    void
  160. free_dircontents(dp)
  161.     struct    _dircontents    *dp;
  162. {
  163.     struct _dircontents    *odp;
  164.  
  165.     while (dp) {
  166.         if (dp->_d_entry)
  167.             free(dp->_d_entry);
  168.         dp = (odp = dp)->_d_next;
  169.         free((char *) odp);
  170.     }
  171. }
  172.  
  173. static    char    *
  174. getdirent(dir)
  175.     char    *dir;
  176. {
  177.     if (dir != (char *) NULL) {        /* get first entry */
  178.         reg.h.ah = DOSI_FINDF;
  179.         reg.h.cl = ATTRIBUTES;
  180. #if    defined(M_I86LM)
  181.         reg.x.dx = FP_OFF(dir);
  182.         sreg.ds = FP_SEG(dir);
  183. #else
  184.         reg.x.dx = (unsigned) dir;
  185. #endif
  186.     } else {                /* get next entry */
  187.         reg.h.ah = DOSI_FINDN;
  188. #if    defined(M_I86LM)
  189.         reg.x.dx = FP_OFF(dtapnt);
  190.         sreg.ds = FP_SEG(dtapnt);
  191. #else
  192.         reg.x.dx = (unsigned) dtapnt;
  193. #endif
  194.     }
  195. #if    defined(M_I86LM)
  196.     intdosx(®, &nreg, &sreg);
  197. #else
  198.     intdos(®, &nreg);
  199. #endif
  200.     if (nreg.x.cflag)
  201.         return (char *) NULL;
  202.  
  203.     return dtabuf.d_name;
  204. }
  205.  
  206. static    void
  207. mysetdta()
  208. {
  209.     reg.h.ah = DOSI_SDTA;
  210. #if    defined(M_I86LM)
  211.     reg.x.dx = FP_OFF(dtapnt);
  212.     sreg.ds = FP_SEG(dtapnt);
  213.     intdosx(®, &nreg, &sreg);
  214. #else
  215.     reg.x.dx = (int) dtapnt;
  216.     intdos(®, &nreg);
  217. #endif
  218. }
  219.